﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BS_2.VTKClass
{
    class SerializeFace
    {

        ContourZone contourZone;
        float vbb1;
        int indexVal;
        Dictionary<String, List<float>> vars;
        Form1 mianform;
        bool istiwangge;
        float xlen, ylen, zlen;
        internal void borderNewLimit(object[] data)
        {
            contourZone = (ContourZone)data[0];
            vbb1 = (float)data[1];
            indexVal = (int)data[2];
            vars = (Dictionary<String, List<float>>)data[3];
            mianform = (Form1)data[4];
            istiwangge = (bool)data[5];
            xlen = contourZone.getXYZLen()[0];
            ylen = contourZone.getXYZLen()[1];
            zlen = contourZone.getXYZLen()[2];
            init();

        }

        Dictionary<float, List<int>> mapX = new Dictionary<float, List<int>>();
        Dictionary<float, List<int>> mapY = new Dictionary<float, List<int>>();
        Dictionary<float, List<int>> mapZ = new Dictionary<float, List<int>>();

        Dictionary<float, Dictionary<float, Dictionary<float, int>>> mapxyz;
        Dictionary<string, int> pToInxmap = new Dictionary<string, int>();
        List<int> listPoint;

        private void init()
        {

            listPoint = new List<int>();
            mapX = new Dictionary<float, List<int>>();
            mapY = new Dictionary<float, List<int>>();
            mapZ = new Dictionary<float, List<int>>();
            mapxyz = new Dictionary<float, Dictionary<float, Dictionary<float, int>>>();

            String varName = mianform.varNow;
            float max = mianform.varlimitData[1];
            float min = mianform.varlimitData[0];


            ZoneData zoneData = contourZone.zoneData;
            //创建每个域数据包
            Zone zone = new Zone();
            Dictionary<String, List<float>> varMap = zone.getVarMap();
            List<float> listvar = new List<float>();
            varMap.Add(varName, listvar);
            List<P3D> Points = zone.getPoints();

            for (int i = 0; i < zoneData.centerX_LS.Count(); i++)
            {

                float val = vars[varName][i];//当前单元的中心变量值
                float x = zoneData.centerX_LS[i];
                float y = zoneData.centerY_LS[i];
                float z = zoneData.centerZ_LS[i];
                listvar.Add(val);
                Points.Add(new P3D(x, y, z));
                string k = "" + x + y + z;
                pToInxmap.Add(k, i);
                if (val > max || val < min)//获取区间单元
                {
                    continue;
                }

                listPoint.Add(i);
                if (!mapX.ContainsKey(x))
                {
                    mapX.Add(x, new List<int>());

                }
                mapX[x].Add(i);
            }
            //获取每个点的坐标方式
            foreach (var item in mapX)
            {
                List<int> listx = item.Value;//每一个x平面的数据 
                Dictionary<float, List<int>> mapYface = new Dictionary<float, List<int>>();
                for (int i = 0; i < listx.Count; i++)
                {
                    int index = listx[i];
                    float ykey = zoneData.centerY_LS[index];

                    if (!mapYface.ContainsKey(ykey))
                    {
                        mapYface.Add(ykey, new List<int>());

                    }
                    mapYface[ykey].Add(index);
                }

                Dictionary<float, Dictionary<float, int>> mapXY = new Dictionary<float, Dictionary<float, int>>();
                foreach (var itemxy in mapYface)
                {//便利Y得到Z 
                    List<int> listz = itemxy.Value;//每一个x平面的数据 
                    Dictionary<float, int> mapZface = new Dictionary<float, int>();
                    for (int i = 0; i < listz.Count; i++)
                    {
                        int index = listz[i];
                        float zkey = zoneData.centerZ_LS[index];
                        mapZface.Add(zkey, index);
                    }
                    mapXY.Add(itemxy.Key, mapZface);
                }
                //保存y列数据
                mapxyz.Add(item.Key, mapXY);
                mapYface.Clear();
            }
            mapX.Clear();

            //获取可能链接成面的点
            Dictionary<int, List<int>> pkmap = new Dictionary<int, List<int>>();
            //   Dictionary<string, int > triangleFace = new Dictionary<string, int >();//k:三角面名称  v:面使用次数


            for (int h = 0; h < listPoint.Count(); h++)
            {
                int i = listPoint[h];
                float x = zoneData.centerX_LS[i];
                float y = zoneData.centerY_LS[i];
                float z = zoneData.centerZ_LS[i];
                float kx = x + xlen;
                float ky = y + ylen;
                float kz = z + zlen;
                float cx = x - xlen;
                float cy = y - ylen;
                float cz = z - zlen;

                if (mapxyz.ContainsKey(kx) && mapxyz[kx].ContainsKey(y) && mapxyz[kx][y].ContainsKey(z))
                {
                    int cc1 = mapxyz[kx][y][z];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }
                    pkmap[i].Add(cc1);

                }
                if (mapxyz.ContainsKey(cx) && mapxyz[cx].ContainsKey(y) && mapxyz[cx][y].ContainsKey(z))
                {
                    int cc1 = mapxyz[cx][y][z];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }
                    pkmap[i].Add(cc1);

                }

                if (mapxyz[x].ContainsKey(ky) && mapxyz[x][ky].ContainsKey(z))
                {
                    int cc1 = mapxyz[x][ky][z];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }

                    //添加当前面
                    pkmap[i].Add(cc1);

                }
                if (mapxyz[x].ContainsKey(cy) && mapxyz[x][cy].ContainsKey(z))
                {
                    int cc1 = mapxyz[x][cy][z];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }

                    pkmap[i].Add(cc1);


                }


                if (mapxyz[x][y].ContainsKey(kz))
                {
                    int cc1 = mapxyz[x][y][kz];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }


                    pkmap[i].Add(cc1);


                }

                if (mapxyz[x][y].ContainsKey(cz))
                {
                    int cc1 = mapxyz[x][y][cz];

                    if (!pkmap.ContainsKey(i))
                    {
                        pkmap.Add(i, new List<int>());

                    }

                    pkmap[i].Add(cc1);

                }

            }


            mapxyz.Clear();

            foreach (var item in pkmap)
            {
                List<int> list = item.Value;
                int inx = item.Key;
                if (list.Count < 6)//外围裸漏点
                {

                    //for (int i = 1; i < list.Count; i++)
                    //{

                    //    int ic =  list[i];

                    //    for (int j = 0; j < i; j++)
                    //    {
                    //        int cc = list[j];
                    //        bool boo = isTriangle(inx, ic , cc, zoneData);
                    //        if (boo)
                    //        {
                    //            Face face = new Face(new int[] { inx, ic, cc });
                    //            zone.getFaces().Add(face); 

                    //        }
                    //    } 
                    //}

                    for (int i = 1; i < list.Count; i++)
                    {

                        int ic = list[i];
                        if (pkmap.ContainsKey(ic))//&& lsMap[ic].Count < 6
                        {
                            for (int j = 0; j < i; j++)
                            {
                                int cc = list[j];
                                if (pkmap.ContainsKey(cc))// && lsMap[cc].Count < 6
                                {
                                    P3D pe = isPolygon(inx, ic, cc, zoneData);
                                    int inxe = pToInxmap["" + pe.getX() + pe.getY() + pe.getZ()];
                                    if (pe != null)
                                    {

                                        if (pkmap.ContainsKey(inxe))
                                        {
                                            //if (lsMap[inxe].Count < 6)
                                            {
                                                Face face = new Face(new int[] { inx, ic, inxe, cc });
                                                zone.getFaces().Add(face);
                                            }
                                        }

                                    }

                                }
                            }

                        }
                    }
                }
            }

            pkmap.Clear();

            zone.setPoints(Points);

            contourZone.zones.Add(zone);


        }


        private P3D isPolygon(int center, int c1, int c2, ZoneData zoneData)
        {
            P3D nor1 = new P3D(
                   zoneData.centerX_LS[c1] - zoneData.centerX_LS[center],
                   zoneData.centerY_LS[c1] - zoneData.centerY_LS[center],
                   zoneData.centerZ_LS[c1] - zoneData.centerZ_LS[center]);

            P3D nor2 = new P3D(
                zoneData.centerX_LS[c2] - zoneData.centerX_LS[center],
                zoneData.centerY_LS[c2] - zoneData.centerY_LS[center],
                zoneData.centerZ_LS[c2] - zoneData.centerZ_LS[center]);



            bool boo = false;
            float len = nor1.dotProduct(nor2);
            if (len < 0.01)
                boo = true;
            if (boo)
            {
                P3D pn = nor1.add(nor2);
                P3D pe = pn.add(zoneData.centerX_LS[center], zoneData.centerY_LS[center], zoneData.centerZ_LS[center]);
                return pe;
            }
            return null;
        }


        private string getTriangleName(int inx, int i, int cc1, ZoneData zoneData)
        {

            List<int> list = new List<int>() { inx, i, cc1 };
            string name = list.Min() + "_" + list.Max() + "_";
            list.Remove(list.Min());
            list.Remove(list.Max());
            name += list[0];
            list.Clear();
            return name;
        }




        private bool isTriangle(int center, int c1, int c2, ZoneData zoneData)
        {
            P3D nor1 = new P3D(zoneData.centerX_LS[center] - zoneData.centerX_LS[c1],
                zoneData.centerY_LS[center] - zoneData.centerY_LS[c1],
                zoneData.centerZ_LS[center] - zoneData.centerZ_LS[c1]);

            P3D nor2 = new P3D(zoneData.centerX_LS[center] - zoneData.centerX_LS[c2],
              zoneData.centerY_LS[center] - zoneData.centerY_LS[c2],
              zoneData.centerZ_LS[center] - zoneData.centerZ_LS[c2]);
            float len = nor1.dotProduct(nor2);
            if (len == 0)
                return true;
            return false;
        }


    }
}
